package fm.yichenet.mongo.service.impl;

import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import fm.cache.AreaCache;
import fm.dao.MongoBaseDao;
import fm.exception.BizException;
import fm.mongo.MCondition;
import fm.mongo.MRel;
import fm.mongo.MongoTable;
import fm.util.CommonUtils;
import fm.web.CurrentRequest;
import fm.yichenet.mongo.service.ExpressService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.regex.Pattern;

/**
 * Created by CM on 2017/6/27.
 */
@Service
public class ExpressServiceImpl implements ExpressService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ExpressService.class);

    @Autowired
    MongoBaseDao mongoBaseDao;

    @Override
    public List<DBObject> getExpressList(String keyword, String shopId, String area) throws Exception {
        MCondition mc = MCondition.create(MRel.and);

        if (StringUtils.isNotEmpty(keyword)) {
            mc.append(MCondition.create(MRel.regex).append("name", Pattern.compile("keyword")));
        }

        if (StringUtils.isNotEmpty(area)) {
            mc.append("province", area);
        }

        if (shopId != null) {
            mc.append("wx_user_id", shopId);
        } else {
            mc.append(MCondition.create(MRel.exists).append("wx_user_id", true));
        }


        List<DBObject> express = (List<DBObject>) mongoBaseDao.getList(mc.toDBObject().toMap(), DBObject.class, MongoTable.express);
        if(CollectionUtils.isEmpty(express)){
            addDefaultExpressWithShop(shopId);
        }
        express = (List<DBObject>) mongoBaseDao.getList(mc.toDBObject().toMap(), DBObject.class, MongoTable.express);
        return express;
    }

    @Override
    public DBObject getExpress(String expressId) {
        if (StringUtils.isEmpty(expressId)) {
            throw new BizException("参数缺失！");
        }

        return (DBObject) mongoBaseDao.findOne(new BasicDBObject("express_id", expressId).toMap(), DBObject.class, MongoTable.express);
    }

    @Override
    public DBObject updateExpress(String name, String area, Double fee, String expressId) {
        if (StringUtils.isEmpty(expressId)) {
            throw new BizException("参数缺失!");
        }

        DBObject update = new BasicDBObject();

        if (StringUtils.isNotEmpty(name)) {
            update.put("name", name);
        }


        if (StringUtils.isNotEmpty(area)) {
            update.put("province", area);
        }

        if (fee != null) {
            update.put("fee", fee);
        } else {
            update.put("fee", 0L);
        }
        mongoBaseDao.updateOne(new BasicDBObject("express_id", expressId).toMap(), update.toMap(), MongoTable.express);

        update.put("express_id", expressId);
        return update;
    }

    @Override
    public void deleteExpress(String expressId) {
        if (StringUtils.isEmpty(expressId)) {
            throw new BizException("参数缺失!");
        }
        mongoBaseDao.delete(new BasicDBObject("express_id", expressId).toMap(), MongoTable.express);

    }

    @Override
    public DBObject addExpress(String name, Double fee, String area) throws Exception {

        if (StringUtils.isEmpty(name)) {
            throw new BizException("物流名称不能为空！");
        }
        if (StringUtils.isEmpty(area)) {
            throw new BizException("物流覆盖区域不能为空");
        }

        if (fee == null) {
            throw new BizException("费用不能为空!");
        }

        if (fee < 0) {
            throw new BizException("费用不能小于0！");
        }

        DBObject object = new BasicDBObject();
        String expressId = UUID.randomUUID().toString().replaceAll("-", "");
        object.put("express_id", expressId);
        object.put("name", name);
        object.put("fee", fee);
        object.put("province", area);
        object.put("wx_user_id", CurrentRequest.getCurrentUserId());
        object.put("province_desc", area.equals("default") ? "全国默认" : AreaCache.getAddress(area));

        mongoBaseDao.insert(object, MongoTable.express);

        return object;

    }

    @Override
    public DBObject addDefaultExpressWithShop(String shopId) throws Exception {

        DBObject object = new BasicDBObject();

        object.put("name", "到付");
        object.put("fee", new Double(0));
        object.put("province", "default");
        object.put("wx_user_id", shopId);
        object.put("province_desc", "全国默认");

        DBObject express = (DBObject) mongoBaseDao.findOne(object.toMap(),DBObject.class,MongoTable.express);
        LOGGER.info("添加默认到付物流");
        if(express == null){
            String expressId = UUID.randomUUID().toString().replaceAll("-", "");
            object.put("express_id", expressId);
            mongoBaseDao.insert(object, MongoTable.express);
            return object;
        }else{
            return express;
        }

    }

    @Override
    public List<DBObject> getExpressListByGoodId(String goodId,String shopId, String area) throws Exception {

        MCondition mc = MCondition.create(MRel.and);
        mc.append("good_id",goodId);
        DBObject good = (DBObject) mongoBaseDao.findOne(mc.toDBObject().toMap(),DBObject.class,MongoTable.good);
        if(CommonUtils.isEmpty(good)){
           return Collections.EMPTY_LIST;
        }

        MCondition mcExpress = MCondition.create(MRel.and);
        if (StringUtils.isNotEmpty(area)) {
            mcExpress.append("province", area);
        }

        BasicDBList list = (BasicDBList)good.get("good_express");
        if(CollectionUtils.isEmpty(list)){
            DBObject defaultExpress = addDefaultExpressWithShop(shopId);
            list = new BasicDBList();
            list.add(defaultExpress.get("express_id"));
            good.put("good_express",list);
            Map<String,Object> query = new HashedMap();
            query.put("good_id",good.get("good_id"));
            mongoBaseDao.updateOne(query,good.toMap(),MongoTable.good);
        }
        MCondition mcExpressId = MCondition.create(MRel.in);
//        List<String> queryList = new ArrayList<>();
//        for(int i = 0; i < list.size(); i++){
//            queryList.add((String)list.get(i));
//        }
        mcExpressId.append("express_id",list);
        mcExpress.append(mcExpressId);
        List<DBObject> express = (List<DBObject>) mongoBaseDao.getList(mcExpress.toDBObject().toMap(), DBObject.class, MongoTable.express);
        return express;
    }
}
